#include<bits/stdc++.h>
#define dbg(s) cout<<s<<"\n";
#define lowbit(x) ((x)&(-x))
using namespace std;
using ll = long long;
constexpr ll MAXL = 1e6+9, MAXN = 1e5+9;
ll df[MAXL];
ll gp[MAXL];
bool af[MAXL];

ll n,m,L,V;

struct Car{
    ll d,v,a;

    ll outedL = 0, outedR = 0; // Out of speed, from [outedL, outedR]
    bool canbeseen = true;
};

void adds(ll k, ll x){
    while(k<=n){
        df[k] += x;
        k += lowbit(k);
    }
}

ll sums(ll k){
    ll sum = 0;
    while(k>0){
        sum += df[k];
        k -= lowbit(k);
    }

    return sum;
}

// Does [s, t] has a Camara?
bool haveCam(ll s, ll t){
    // // dbg(sums(t));
    // if(sums(t) - sums(s-1) >= 1)   return true;
    // return false;
    for(int i=s;i<=t;i++)   if(af[i] == true)   return true;

    return false;
};

bool ncars_cmp(pair<ll, ll> a, pair<ll, ll> b){
    return a.second < b.second;
}

void CamaraBuild(){
    for(ll i=0;i<=L;i++) if(af[i]){
        adds(i,1);
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // freopen("detect.in", "r", stdin);
    // freopen("detect.out", "w", stdout);

    int t;
    cin>>t;
    while(t--){
        cin>>n>>m>>L>>V;
        memset(df, 0, (n+1) * sizeof(ll));
        memset(af, 0, (n+1) * sizeof(bool));
        ll ans2 = 0;

        vector<Car> cars;
        vector<pair<ll, ll> > ncars; // [l,r] out of space
        vector<ll> camaras;     // camaras' pos
        for(int i=1;i<=n;i++){
            ll d,v,a;
            cin>>d>>v>>a;
            cars.push_back({d,v,a});
        }

        for(int i=1;i<=m;i++){
            ll pos;
            cin>>pos;
            af[pos] = 1;
            camaras.push_back(pos);
        }

        CamaraBuild();
        // for(int i=0;i<=L;i++)   cout<<sums(i);


        for(auto item: cars){
            ll d = item.d, v = item.v, a = item.a;
            if(a == 0){
                if(v>V) item.outedL = item.d, item.outedR = L;
                else    item.canbeseen = false;
            } else if(a > 0){
                ll driven = (V*V-v*v) / (2*a); // here must be lower def
                driven = abs(driven);
                item.outedL = d + driven, item.outedR = L;
            } else if(a < 0){
                if(v<=V)    item.canbeseen = false;
                else{
                    ll driven = (V*V-v*v) / (2*a);
                    driven = abs(driven);
                    item.outedL = d, item.outedR = d + driven;
                }
            }

            // cout<<item.outedL<<"\n";
            if(item.canbeseen == true && haveCam(item.outedL, item.outedR) == true){
                // dbg("has!")
                ans2 ++;
                ncars.push_back({item.outedL, item.outedR});
                
            }
        }

        sort(ncars.begin(), ncars.end(), ncars_cmp);

        ll ans = 0;

        ll tempr = -1;  // note last camara can write cars from [l, r]
        ll tempa = 0, tempb = 0;
        for(ll i = 0, j = 0; i<camaras.size() && j<ncars.size();i++){
            tempa = j, tempb = j;
            while(ncars[j].first <= camaras[i] && camaras[i] <= ncars[j].second){
                tempb = j;
                j++;
            }

            if(tempa > tempr)   ans ++, tempr = tempb;
        }

        cout<<ans2<<" "<<n - ans<<"\n";
        
    }

    return 0;
}